﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ParboiledSharp.parboiled.rules;
using ParboiledSharp.parboiled.dataobjects;
using System.Globalization;
using ParboiledSharp.lang.roboline.utils;
using ParboiledSharp.lang.roboline.ast;

namespace ParboiledSharp.lang.roboline.grammar
{
    partial class RoboLineGrammar : BaseParser
    {
        private Rule ___pushIntegerRule()
        {
            return ACTION(delegate(Context c)
            {
                string strDigit = c.GetMatch();
                int value = int.Parse(strDigit);
                PushInt pushInt = new PushInt(value);
                c.Push(pushInt);
            });
        }

        private Rule ___pushDoubleRule()
        {
            return ACTION(delegate(Context c)
            {
                string strDigit = c.GetMatch();
                double value = StringUtils.Str2Dbl(strDigit);
                PushDouble pushDouble = new PushDouble(value);
                c.Push(pushDouble);
            });
        }

        private Rule ___pushTrueFalseRule(bool tru)
        {
            return ACTION(delegate(Context c)
            {
                c.Push(new PushBoolean(tru));
            });
        }

        private Rule ___pushStringRule()
        {
            return ACTION(delegate(Context c)
            {
                string str = c.GetMatch();
                string unquote = StringUtils.StripQuotes(str);
                string unescaped = StringUtils.unescapeString(unquote);
                ParboiledSharp.lang.roboline.ast.PushString pushString = new ParboiledSharp.lang.roboline.ast.PushString(unescaped);
                c.Push(pushString);
            });
        }

        private Rule ___pushMulDiv()
        {
            return ACTION(delegate(Context c)
            {
                string operation = (string)c.PopObjectWithThePrefix("MUL_DIV_OPERATOR");
                operation=operation.Trim();
                AbstractChunk chunk;
                if (operation == "*")
                {
                    chunk = new Multiple();
                }
                else {
                    chunk = new Divide();
                }
                c.Push(chunk);
            });
        }

        private Rule ___pushAddSub()
        {
            return ACTION(delegate(Context c)
            {
                string operation = c.PopObjectWithThePrefix("PLUS_MINUS_OPERATOR");
                operation = operation.Trim();
                AbstractChunk chunk;
                if (operation == "+")
                {
                    chunk = new Add();
                }
                else
                {
                    chunk = new Subtract();
                }
                c.Push(chunk);
            });
        }

        private Rule ___pushUnaryMinus()
        {
            return ACTION(delegate(Context c)
            {
                c.Push(new PushInt(1));
                c.Push(new Subtract());
            });
        }

        private Rule ___pushIncrement()
        {
            return ACTION(delegate(Context c)
            {
                c.Push(new PushInt(1));
                c.Push(new Add());
            });
        }

        private Rule ___pushDecrement()
        {
            return ACTION(delegate(Context c)
            {
                c.Push(new PushInt(1));
                c.Push(new Subtract());
            });
        }

        private Rule ___pushCompare()
        {
            return ACTION(delegate(Context c)
            {
                string operation = (string)c.PopObjectWithThePrefix("EQUALITY_OPERATOR");
                operation = operation.Trim();
                Compare chunk=new Compare(operation);
                c.Push(chunk);
            });
        }

        private Rule ___pushAnd()
        {
            return ACTION(delegate(Context c)
            {
                c.Push(new And());
            });
        }

        private Rule ___pushOr()
        {
            return ACTION(delegate(Context c)
            {
                c.Push(new Or());
            });
        }
    }
}
